package com.xstudio.pvzreborn.block.machine;

import com.xstudio.pvzreborn.PVZReborn;
import com.xstudio.pvzreborn.block.PVZBlockBase;
import com.xstudio.pvzreborn.block.entity.PVZMachineBlockEntityBase;
import com.xstudio.pvzreborn.utils.LevelUtils;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityTicker;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.network.NetworkHooks;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.annotation.ParametersAreNonnullByDefault;

@ParametersAreNonnullByDefault
@SuppressWarnings("deprecation")
public abstract class PVZBlockMachine extends PVZBlockBase implements EntityBlock {
	public final String guiTransKey;

	public PVZBlockMachine(Properties pProperties, String name) {
		super(pProperties, name);
		guiTransKey = "gui." + PVZReborn.MOD_ID + "." + name;
	}

	@Nullable
	@Override
	public abstract <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level pLevel, BlockState pState, BlockEntityType<T> pBlockEntityType);

	@Override
	public @NotNull InteractionResult use(BlockState pState, Level pLevel, BlockPos pPos, Player pPlayer, InteractionHand pHand, BlockHitResult pHit) {
		if (!pLevel.isClientSide && pLevel.getBlockEntity(pPos) instanceof PVZMachineBlockEntityBase) {
			NetworkHooks.openGui((ServerPlayer) pPlayer, createMenuProvider(pLevel, pPos, pPlayer), pPos);
		}
		return InteractionResult.SUCCESS;
	}

	@Override
	public void onRemove(BlockState pState, Level pLevel, BlockPos pPos, BlockState pNewState, boolean pIsMoving) {
		if (pLevel.getBlockEntity(pPos) instanceof PVZMachineBlockEntityBase machine) {
			for (IItemHandler handler : machine.getAllItemStackHandler()) {
				for (int slot = 0; slot < handler.getSlots(); slot++) {
					ItemEntity drop = LevelUtils.newItemEntity(pLevel, pPos, handler.getStackInSlot(slot));
					drop.setDefaultPickUpDelay();
					pLevel.addFreshEntity(drop);
				}
			}
		}
		super.onRemove(pState, pLevel, pPos, pNewState, pIsMoving);
	}

	/**
	 * @author Bread_NiceCat
	 */
	@Override
	public BlockState getStateForPlacement(BlockPlaceContext pContext) {
		return this.defaultBlockState().setValue(BlockStateProperties.HORIZONTAL_FACING, pContext.getHorizontalDirection().getOpposite());
	}

	public abstract MenuProvider createMenuProvider(Level pLevel, BlockPos pPos, Player pPlayer);

	/**
	 * @author Bread_NiceCat
	 */
	@Override
	protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> pBuilder) {
		pBuilder.add(BlockStateProperties.HORIZONTAL_FACING);
	}

}
